package main

import "fmt"

/**
添加工厂种类,符合开闭原则
添加生产物品种类,需要去修改生产物品种类的方法从而去修改抽象工厂的接口,不符合开闭原则
*/

// 抽象工厂方法模式
type Factory interface {
	CreateA() Item
	CreateB() Item
	CreateC() Item
}

type FactoryPlus interface {
	CreateD() Item
}

type FactoryA struct {
}

type FactoryB struct {
}

type FactoryC struct {
}

type FactoryD struct {
}

func (f FactoryD) CreateA() Item {
	fmt.Println("这是D工厂...")
	return new(A)
}

func (f FactoryD) CreateB() Item {
	fmt.Println("这是D工厂...")
	return new(B)
}

func (f FactoryD) CreateC() Item {
	fmt.Println("这是D工厂...")
	return new(C)
}

func (f FactoryD) CreateD() Item {
	fmt.Println("这是D工厂...")
	return new(D)
}

func (f FactoryA) CreateA() Item {
	fmt.Println("这是A工厂...")
	return new(A)
}

func (f FactoryA) CreateB() Item {
	fmt.Println("这是A工厂...")
	return new(B)
}

func (f FactoryA) CreateC() Item {
	fmt.Println("这是A工厂...")
	return new(C)
}

func (f FactoryB) CreateA() Item {
	fmt.Println("这是B工厂...")
	return new(A)
}

func (f FactoryB) CreateB() Item {
	fmt.Println("这是B工厂...")
	return new(B)
}

func (f FactoryB) CreateC() Item {
	fmt.Println("这是B工厂...")
	return new(C)
}

func (f FactoryC) CreateA() Item {
	fmt.Println("这是C工厂...")
	return new(A)
}

func (f FactoryC) CreateB() Item {
	fmt.Println("这是C工厂...")
	return new(B)
}

func (f FactoryC) CreateC() Item {
	fmt.Println("这是C工厂...")
	return new(C)
}

type Item interface {
	Show()
}

type A struct {
}

func (a A) Show() {
	fmt.Println("这是A...")
}

type B struct {
}

func (b B) Show() {
	fmt.Println("这是B...")
}

type C struct {
}

func (c C) Show() {
	fmt.Println("这是C...")
}

type D struct {
}

func (d D) Show() {
	fmt.Println("这是D...")
}

func main() {
	//创建一个A工厂的B和B工厂的C
	new(FactoryA).CreateB().Show()
	new(FactoryB).CreateC().Show()
	//创建C工厂的C
	new(FactoryC).CreateC().Show()
	//在不修改原有抽象工厂接口的基础上扩展D产品
	//1.新增一个抽象工厂接口
	//2.实现该抽象工厂接口
	new(FactoryD).CreateD().Show()
}
